import type { Machine, Database, Alarm, UserInfo, ApiResponse, LoginResponse, AgentConfig } from '../types'
import { API_BASE_URL, API_ENDPOINTS, USE_MOCK_DATA } from '../config/api'
import { mockMachines, mockDatabases, mockAlarms } from '../data/mockData'
import { clearAuthStorage } from '../utils'
import { API_TIMEOUT } from '../constants'
import { logger } from '../utils'
import ErrorHandler from '../utils/errorHandler'

// 通用请求函数
interface RequestOptions extends RequestInit {
  timeout?: number
}

const request = async <T = any>(url: string, options: RequestOptions = {}): Promise<ApiResponse<T>> => {
  const { timeout = API_TIMEOUT, ...fetchOptions } = options
  
  try {
    // 添加认证token
    const token = localStorage.getItem('authToken')
    const headers: HeadersInit = {
      'Content-Type': 'application/json',
      ...fetchOptions.headers,
    }
    
    if (token && !url.includes('/auth/login')) {
      headers['Authorization'] = `Bearer ${token}`
    }

    // 创建超时控制
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), timeout)

    logger.debug('发送API请求', { 
      url: `${API_BASE_URL}${url}`, 
      method: fetchOptions.method || 'GET',
      hasToken: !!token 
    })
    
    const startTime = Date.now()
    const response = await fetch(`${API_BASE_URL}${url}`, {
      ...fetchOptions,
      headers,
      signal: controller.signal,
    })

    logger.info('API应答:', response)

    clearTimeout(timeoutId)
    const duration = Date.now() - startTime
    
    logger.debug('收到API响应', { 
      url: `${API_BASE_URL}${url}`, 
      status: response.status, 
      duration: `${duration}ms` 
    })

    if (!response.ok) {
      logger.error('API请求失败', { 
        url: `${API_BASE_URL}${url}`, 
        status: response.status, 
        statusText: response.statusText,
        duration: `${duration}ms`
      })
      
      // 如果是401未授权，清除token并跳转到登录页
      if ( (response.status === 401) && (response.url && !response.url.includes('/auth/login'))) {
        logger.warn('用户认证失败，需要重新登录', { url: `${API_BASE_URL}${url}` })
        clearAuthStorage()
        // 使用 router 实例而不是直接修改 window.location
        // 这样可以更好地与 Vue Router 集成
        window.location.href = '/login'
        throw new Error('Unauthorized')
      }
      
      // 尝试解析错误响应
      try {
        const errorData = await response.json()
        throw new Error(errorData.message || `HTTP error! status: ${response.status}`)
      } catch(err) {
        logger.error('API响应解析失败', { 
          url: `${API_BASE_URL}${url}`, 
          error: err.message || err,
          stack: err.stack
        })
        // 将后台的服务，返回到前端页面进行打印
        if (err.message) {
          throw new Error(`[${err.message}]`)
        } else {
          throw new Error(`HTTP error! status: ${response.status}`)
        }
      }
    }

    const data: ApiResponse<T> = await response.json()
    logger.debug('API请求成功', { 
      url: `${API_BASE_URL}${url}`, 
      data: typeof data === 'object' ? `${JSON.stringify(data).substring(0, 100)}...` : data,
      duration: `${duration}ms`
    })
    return data
  } catch (error: any) {
    if (error.name === 'AbortError') {
      logger.error('API请求超时', { url: `${API_BASE_URL}${url}`, timeout })
      const timeoutError = new Error('Request timeout')
      timeoutError.name = 'TIMEOUT'
      throw timeoutError
    }
    logger.error('API请求过程中发生错误', { 
      url: `${API_BASE_URL}${url}`, 
      error: error.message || error,
      stack: error.stack
    })
    throw error
  }
}

// 认证 API
export const authAPI = {
  // 登录
  login: async (username: string, password: string): Promise<ApiResponse<LoginResponse>> => {
    logger.info('开始用户登录流程', { username, password })
    return request<LoginResponse>(API_ENDPOINTS.login, {
      method: 'POST',
      body: JSON.stringify({ username, password })
    })
  },

  // 登出
  logout: async (): Promise<ApiResponse<void>> => {
    logger.info('开始用户登出流程')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据进行登出')
      return new Promise((resolve) => {
        setTimeout(() => {
          clearAuthStorage()
          logger.info('模拟登出成功')
          resolve({
            success: true,
            message: '登出成功'
          })
        }, 300)
      })
    }
    
    logger.debug('向后端发送登出请求')
    return request<void>(API_ENDPOINTS.logout, {
      method: 'POST'
    })
  },

  // 获取用户信息
  getUserInfo: async (): Promise<ApiResponse<UserInfo>> => {
    logger.debug('开始获取用户信息')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取用户信息')
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const userInfo = localStorage.getItem('userInfo')
          if (userInfo) {
            logger.debug('获取模拟用户信息成功')
            resolve({
              success: true,
              data: JSON.parse(userInfo)
            })
          } else {
            logger.warn('获取模拟用户信息失败: 未登录')
            reject({
              success: false,
              message: '未登录'
            })
          }
        }, 300)
      })
    }
    
    logger.debug('向后端请求用户信息')
    return request<UserInfo>(API_ENDPOINTS.getUserInfo)
  },

  // 刷新Token
  refreshToken: async () => {
    logger.debug('开始刷新认证令牌')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据刷新令牌')
      return new Promise((resolve) => {
        setTimeout(() => {
          const newToken = 'mock-token-' + Date.now()
          logger.debug('模拟令牌刷新成功')
          resolve({
            success: true,
            data: {
              token: newToken,
              expiresIn: 3600
            }
          })
        }, 300)
      })
    }
    
    logger.debug('向后端发送令牌刷新请求')
    return request<{token: string, expiresIn: number}>(API_ENDPOINTS.refreshToken, {
      method: 'POST'
    })
  },

  // 验证Token是否有效
  validateToken: async () => {
    logger.debug('开始验证认证令牌')
    
    if (USE_MOCK_DATA) {
      return new Promise((resolve) => {
        const token = localStorage.getItem('authToken')
        logger.debug('使用模拟数据验证令牌', { valid: !!token })
        resolve({
          success: !!token,
          valid: !!token
        })
      })
    }
    
    logger.debug('向后端发送令牌验证请求')
    return request<UserInfo>(API_ENDPOINTS.getUserInfo)
  }
}

export const machineAPI = {
  // 获取所有机器信息
  getAll: async (skip: number = 0, limit: number = 100, status?: string) => {
    logger.debug('开始获取所有机器信息')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取机器信息')
      // 开发环境：返回模拟数据
      return new Promise((resolve) => {
        setTimeout(() => resolve({
          success: true,
          data: mockMachines
        }), 300) // 模拟网络延迟
      })
    }
    // 生产环境：调用真实 API
    let url = `${API_ENDPOINTS.machines}?skip=${skip}&limit=${limit}`;
    if (status) {
      url += `&status=${status}`;
    }
    logger.debug('向后端请求所有机器信息')
    return request<Machine[]>(url)
  },

  // 获取单个机器详情
  getById: async (id: number | string) => {
    logger.debug('开始获取机器详情', { id })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取机器详情', { id })
      return new Promise((resolve) => {
        const machine = mockMachines.find(m => m.id === id)
        setTimeout(() => resolve({
          success: true,
          data: machine
        }), 200)
      })
    }
    
    logger.debug('向后端请求机器详情', { id })
    return request<Machine>(API_ENDPOINTS.machineDetail(id))
  },
  
  // 创建新机器
  create: async (machineData: Partial<Machine>) => {
    logger.debug('开始创建新机器', machineData)
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据创建机器')
      return new Promise((resolve) => {
        setTimeout(() => {
          const newMachine = {
            ...machineData,
            id: mockMachines.length + 1,
            status: 'offline' as const,
            cpu: 0,
            memory: 0,
            disk: 0,
            createTime: new Date().toLocaleString('zh-CN')
          }
          mockMachines.push(newMachine as any)
          resolve({
            success: true,
            data: newMachine
          })
        }, 300)
      })
    }
    
    logger.debug('向后端发送创建机器请求')
    return request<Machine>(API_ENDPOINTS.machines, {
      method: 'POST',
      body: JSON.stringify(machineData)
    })
  },
  
  // 更新机器信息
  update: async (id: number, machineData: Partial<Machine>) => {
    logger.debug('开始更新机器信息', { id, machineData })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据更新机器')
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const index = mockMachines.findIndex(m => m.id === id)
          if (index !== -1) {
            mockMachines[index] = { ...mockMachines[index], ...machineData }
            resolve({
              success: true,
              data: mockMachines[index]
            })
          } else {
            reject({
              success: false,
              message: '机器不存在'
            })
          }
        }, 300)
      })
    }
    
    logger.debug('向后端发送更新机器请求')
    return request<Machine>(API_ENDPOINTS.machineDetail(id), {
      method: 'PUT',
      body: JSON.stringify(machineData)
    })
  },
  
  // 删除机器
  delete: async (id: number) => {
    logger.debug('开始删除机器', { id })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据删除机器')
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const index = mockMachines.findIndex(m => m.id === id)
          if (index !== -1) {
            mockMachines.splice(index, 1)
            resolve({
              success: true,
              message: '删除成功'
            })
          } else {
            reject({
              success: false,
              message: '机器不存在'
            })
          }
        }, 300)
      })
    }
    
    logger.debug('向后端发送删除机器请求')
    return request<void>(API_ENDPOINTS.machineDetail(id), {
      method: 'DELETE'
    })
  },
  
  // 更新机器激活状态
  updateActivate: async (id: number, isActivate: boolean) => {
    logger.debug('开始更新机器激活状态', { id, isActivate })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据更新机器激活状态')
      return new Promise((resolve) => {
        setTimeout(() => {
          const index = mockMachines.findIndex(m => m.id === id)
          if (index !== -1) {
            mockMachines[index].is_activate = isActivate
            resolve({
              success: true,
              message: isActivate ? '机器已激活' : '机器已禁用'
            })
          } else {
            resolve({
              success: false,
              message: '机器不存在'
            })
          }
        }, 300)
      })
    }
    
    logger.debug('向后端发送更新机器激活状态请求')
    return request<Machine>(API_ENDPOINTS.machineActivate(id), {
      method: 'PUT',
      body: JSON.stringify({ is_activate: isActivate })
    })
  },

  // 获取机器的Agent配置
  getAgentConfig: async (machineId: number) => {
    logger.debug('开始获取机器Agent配置', { machineId })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取Agent配置')
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({
            success: true,
            data: {
              machine_id: machineId,
              interval: 30,
              collect_system_info: true,
              collect_cpu_info: true,
              collect_memory_info: true,
              collect_disk_info: true,
              collect_network_info: true,
              collect_process_info: false,
              collect_log_info: false,
              collect_database_info: false,
              log_paths: [],
              database_configs: [],
              port_list: []
            }
          })
        }, 300)
      })
    }
    
    // 先获取机器详细信息以获得IP地址
    const machineResponse = await request<Machine>(API_ENDPOINTS.machineDetail(machineId));
    if (!machineResponse.success || !machineResponse.data) {
      return {
        success: false,
        message: '无法获取机器信息'
      };
    }
    
    const machineIp = machineResponse.data.ip;
    logger.debug('向后端请求Agent配置', { machineIp })
    return request<AgentConfig>(`/metrics/agent-config?machine_ip=${machineIp}`, {
      method: 'GET'
    })
  },
  
  // 更新机器的Agent配置
  updateAgentConfig: async (machineId: number, config: Partial<AgentConfig>) => {
    logger.debug('开始更新机器Agent配置', { machineId, config })
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据更新Agent配置')
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({
            success: true,
            message: '配置更新成功'
          })
        }, 300)
      })
    }
    
    logger.debug('向后端发送更新Agent配置请求')
    return request<AgentConfig>(`/metrics/agent-config/${machineId}`, {
      method: 'PUT',
      body: JSON.stringify(config)
    })
  }
}

// 数据库状态 API
export const databaseAPI = {
  // 获取所有数据库状态
  getAll: async () => {
    logger.debug('开始获取所有数据库状态')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取数据库状态')
      return new Promise((resolve) => {
        setTimeout(() => resolve({
          success: true,
          data: mockDatabases
        }), 300)
      })
    }
    
    logger.debug('向后端请求所有数据库状态')
    return request<Database[]>(API_ENDPOINTS.databases)
  },
}

// 告警监控 API
export const alarmAPI = {
  // 获取所有告警信息
  getAll: async () => {
    logger.debug('开始获取所有告警信息')
    
    if (USE_MOCK_DATA) {
      logger.debug('使用模拟数据获取告警信息')
      return new Promise((resolve) => {
        setTimeout(() => resolve({
          success: true,
          data: mockAlarms
        }), 300)
      })
    }
    
    logger.debug('向后端请求所有告警信息')
    return request<Alarm[]>(API_ENDPOINTS.alarms)
  },
}

export default {
  auth: authAPI,
  machine: machineAPI,
  database: databaseAPI,
  alarm: alarmAPI,
}